﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PH.Model.Systems;
using System.Text.RegularExpressions;
namespace PH.Data.Systems
{
    public class BureauCommand
    {
        public static BureauModel GetModel(Guid guid)
        {
            if (guid != Guid.Empty)
            {
                using (DBCentre db = new DBCentre())
                {
                    var dBureau = db.DataContext.Bureaus.FirstOrDefault(p => p.Guid == guid);
                    if (dBureau != null)
                    {
                        var bureau = Convertor.ConvertTo<BureauModel, Bureau>(dBureau);
                        return bureau;
                    }
                }
            }
            return null;   
        }
        public static BureauModel GetModel(int id)
        {
            if (id>0)
            {
                using (DBCentre db = new DBCentre())
                {
                    var dBureau = db.DataContext.Bureaus.FirstOrDefault(p => p.ID==id);
                    if (dBureau != null)
                    {
                        var bureau = Convertor.ConvertTo<BureauModel, Bureau>(dBureau);
                        return bureau;
                    }
                }
            }
            return null;
        }

        public static BureauCollection GetChildren(Guid guid,bool getUser=false,bool withme=false)
        {
            var ret = new BureauCollection();
            var bureau = GetModel(guid);
            if (bureau != null)
            {
                using (DBCentre db = new DBCentre())
                {
                    var q = db.DataContext.Bureaus.Where(p => p.PID == bureau.ID);
                    var n = q.Count();
                    if (n > 0)
                    {
                        q = q.OrderBy(p => p.Code);
                        var lst = q.ToList();
                        ret = Convertor.ConvertCollection<BureauModel, Bureau, BureauCollection>(lst);
                        ret.TotalRecordsCount = n;
                        if (getUser)
                        {
                            ret.ForEach(p => {
                                var d = lst.Find(o => o.ID == p.ID);
                                var u = d.Users.FirstOrDefault(r => r.Roles.Any(o => o.RoleName == "Bureau"));
                                if (u != null)
                                    p.User = Convertor.ConvertTo<PH.Model.Accounts.UserModel, User>(u);
                            });
                        }
                        if (withme)
                        {
                            ret.Insert(0, bureau);
                            ret.TotalRecordsCount += 1;
                        }
                    }
                }
                
            }
            return ret;
        }

        public static BureauModel GetParent(Guid guid)
        {
            if (guid != Guid.Empty)
            {
                using (DBCentre db = new DBCentre())
                {
                    var dBureau = db.DataContext.Bureaus.FirstOrDefault(p => p.Guid == guid);
                    if (dBureau != null && dBureau.PID > 0)
                    {
                        var dParent = db.DataContext.Bureaus.FirstOrDefault(p => p.ID == dBureau.PID);
                        var bureau = Convertor.ConvertTo<BureauModel, Bureau>(dParent);
                        return bureau;
                    }
                }
            }
            return null;   
        }

        public static BureauCollection GetParents(Guid guid)
        {
            var ret=new BureauCollection();
            if (guid != Guid.Empty)
            {
                using (DBCentre db = new DBCentre())
                {
                    var dBureau = db.DataContext.Bureaus.FirstOrDefault(p => p.Guid == guid);
                    while (dBureau != null && dBureau.PID > 0)
                    {
                        var dParent = db.DataContext.Bureaus.FirstOrDefault(p => p.ID == dBureau.PID);
                        var parent = Convertor.ConvertTo<BureauModel, Bureau>(dParent);
                        ret.Add(parent);
                        dBureau = dParent;
                    }
                }
            }
            ret.TotalRecordsCount = ret.Count;
            return ret;
        }

        public static List<int> GetSchoolIDs(Guid guid)
        {
            var ret = new List<int>();
            if (guid != Guid.Empty)
            {
                using (DBCentre db = new DBCentre())
                {
                    var lst = db.DataContext.SchoolInBureaux.Where(p => p.Bureau.Guid == guid).ToList();
                    ret = lst.Select(p => p.SchoolID).ToList();
                }
            }
            return ret;
        }

        public static BureauCollection GetAllChildren(Guid guid,bool withme=false,bool getParent=false,bool getUser=false)
        {
            var ret = new BureauCollection();
            if (guid != Guid.Empty)
            {
                using (DBCentre db = new DBCentre())
                {
                    var bureau = db.DataContext.Bureaus.FirstOrDefault(p => p.Guid == guid);
                    if (bureau != null)
                    {
                        var r = db.DataContext.GetAllChildren(bureau.ID);
                        var q = db.DataContext.Bureaus.Where(p => r.Contains(p.ID));
                        q = q.OrderBy(p => p.Code);
                        var lst = q.ToList();
                        ret = Convertor.ConvertCollection<BureauModel, Bureau, BureauCollection>(lst);
                        ret.TotalRecordsCount = ret.Count;
                        if (withme)
                        {
                            ret.Insert(0, Convertor.ConvertTo<BureauModel,Bureau>(bureau));
                            ret.TotalRecordsCount += 1;
                        }
                    }
                }
            }
            return ret;
        }

        private static void SaveCheck(BureauModel model,DBCentre db)
        {
            if (string.IsNullOrEmpty(model.EduName))
                throw new Utils.PhException("请输入机构名称");
            if (string.IsNullOrEmpty(model.Code) || !Regex.IsMatch(model.Code,@"^\d{4}$"))
                throw new Utils.PhException("请输入正确的机构编码");
            if (db != null)
            {
                if (db.DataContext.Bureaus.Any(p=>p.EduName==model.EduName && p.Guid!=model.Guid))
                    throw new Utils.PhException("机构名称重复，请检查");
                if (db.DataContext.Bureaus.Any(p => p.Code == model.Code && p.Guid != model.Guid))
                    throw new Utils.PhException("机构编码重复，请检查");
            }
        }

        public static void CreateNew(BureauModel model)
        {
            if (model != null)
            {
                using (DBCentre db = new DBCentre())
                {
                    SaveCheck(model,db);
                    model.Guid = Guid.NewGuid();
                    model.CreatedOn = DateTime.Now;
                    var d = Convertor.ConvertFrom<Bureau, BureauModel>(model);
                    db.DataContext.Bureaus.Add(d);

                    #region 创建一个管理员用户
                    var userName = Utils.Password.MakeRandomPassword("LOWER", 8);
                    while (db.DataContext.Users.Any(p => p.UserName == userName))
                    {
                        userName = Utils.Password.MakeRandomPassword("LOWER", 8);
                        System.Threading.Thread.Sleep(100);
                    }
                    var user = new User()
                    {
                        Guid = Guid.NewGuid(),
                        UserName = userName,
                        Password = Utils.Encrypt.MD5Encrypt("888888"),
                        RealName = "机构管理员",
                        Status = 1,
                        CreatedOn = DateTime.Now,
                        AssociatedBureauID = d.ID
                    };
                    var role = db.DataContext.Roles.FirstOrDefault(p => p.RoleName == "Bureau");
                    user.Roles.Add(role);
                    db.DataContext.Users.Add(user);
                    #endregion

                    db.DataContext.SaveChanges();
                }
            }
        }

        public static void Update(BureauModel model)
        {
            if (model != null)
            {
                using (DBCentre db = new DBCentre())
                {
                    var d = db.DataContext.Bureaus.FirstOrDefault(p => p.Guid == model.Guid);
                    if (d != null)
                    {
                        SaveCheck(model, db);
                        Convertor.UpdateValue(model, d);
                        db.DataContext.SaveChanges();
                    }
                }
            }

        }

        public static void Delete(Guid guid)
        {
            if (guid != Guid.Empty)
            {
                using (DBCentre db = new DBCentre())
                {
                    db.Delete<Bureau>(p => p.Guid == guid);
                    db.DataContext.SaveChanges();
                }
            }
        }
    }
}
